﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using EntityCodeBuilder.Entity;

namespace WindowsDemo
{
    public class CreateFileHelper
    {
        /// <summary>
        /// 创建文件目录和文件
        /// </summary>
        /// <param name="tables">所有表</param>
        /// <param name="fileDir">文件目录</param>
        public static void Create(List<TableName> tables, string fileDir)
        {
            CreateDirectory(fileDir);
            foreach (TableName table in tables)
            {
                //实体类名称
                string entityName = GenVarName(table.Name);
                //实体类文件名
                string filePath = Path.Combine(fileDir, entityName + ".cs");

                //生成代码
                string code = CreateFileHelper.BuilderCode(table);

                //写入代码到文件
                File.WriteAllText(filePath, code);
            }
        }

        /// <summary>
        /// 创建文件目录
        /// </summary>
        /// <param name="targetDir"></param>
        private static void CreateDirectory(string targetDir)
        {
            DirectoryInfo dir = new DirectoryInfo(targetDir);
            if (!dir.Exists)
                dir.Create();
        }

        private static string _namesapce = "";

        public static string NameSpace
        {
            get { return _namesapce; }
            set
            {
                if (string.IsNullOrWhiteSpace(value))
                    _namesapce = "";
                else _namesapce = value;
            }
        }

        /// <summary>
        /// 根据表名，生成代码
        /// </summary>
        /// <param name="tbl">表名</param>
        /// <returns></returns>
        public static string BuilderCode(TableName tbl)
        {
            string entityName = GenVarName(tbl.Name);

            StringBuilder sb = new StringBuilder();
            sb.Append("using System;\n");
            sb.Append("using Easy4net.CustomAttributes;\n");
            sb.AppendFormat("namespace {0}", _namesapce.Length > 0 ? _namesapce : "Models").Append("\n");
            sb.Append("{  \n");
            sb.AppendFormat("\t/// <summary>\n\t/// 表名：{0} 说明：{1}\n\t/// </summary>\n", tbl.Name, tbl.Comment);
            sb.Append("\t [Table(Name = \"").Append(tbl.Name).Append("\")] ").Append("\n");
            sb.Append("\t public class ").Append(entityName).Append("\n");
            sb.Append("\t { ").Append("\n");
            string id = null;
            List<TableColumn> columns = TableHelper.GetColumnField(tbl.Name);
            foreach (TableColumn column in columns)
            {
                sb.AppendFormat("\t\t/// <summary>\n\t\t/// 列名：{0} 说明：", column.Name);
                string type = TypeHelper.GetType(column.Type, column.IsNull == "v" ? true : false);
                if (column.IsPrimaryKey == "v")
                {
                    id = column.Name;
                    //[Id(Name = "UserID", Strategy = GenerationType.INDENTITY)]
                    var keytxt = string.Empty;
                    string strategy = "GUID";
                    if (column.IsIdentity == "v")
                    {
                        strategy = "INDENTITY";
                        keytxt = "自增";
                    }
                    else if (type == "string")
                    {
                        strategy = "GUID"; keytxt = "GUID";
                    }
                    else
                    {
                        strategy = "FILL"; keytxt = "手动填写";
                    }
                    sb.Append(keytxt + "主键 ");
                    sb.AppendFormat("{0}\n\t\t/// </summary>\n", column.Comment);
                    sb.Append("\t\t").Append("[Id(Name = \"").Append(column.Name).Append("\", Strategy = GenerationType.").Append(strategy).Append(")]").Append("\n");
                }
                else
                {
                    sb.AppendFormat("{0}\n\t\t/// </summary>\n", column.Comment);
                    if (GenerateColumn) sb.Append("\t\t").Append("[Column(Name = \"").Append(column.Name).Append("\")]").Append("\n");
                }

                string fieldName = GenVarName(column.Name, false);
                sb.Append("\t\t").Append("public ").Append(type).Append(" ").Append(fieldName).Append("{ get; set; } \n\n");
            }
            if (id != null && OverrideGetHashCode) sb.AppendFormat("\n\t\tpublic override int GetHashCode()\n\t\t{{\n\t\t\treturn this.{0}.GetHashCode();\n\t\t}}\n", id);
            if (id != null && OverrideEquals) sb.AppendFormat("\n\t\tpublic bool Equals({0} obj)\n\t\t{{\n\t\t\treturn {1} == obj.{1};\n\t\t}}\n\t\tpublic override bool Equals(object obj)\n\t\t{{\n\t\t\tif (obj == null) return false;\n\t\t\tvar o = obj as {0};\n\t\t\tif (o != null) return Equals(o);\n\t\t\treturn base.Equals(obj);\n\t\t}}\n", tbl.Name, id);
            sb.Append("\t } ").Append("\n");
            sb.Append("}    ").Append("\n");

            return sb.ToString();
        }

        public static bool RemoveTableName_ = false;
        public static bool RemoveColumnName_ = false;
        public static bool CamelCaseName = false;
        public static string tblNamePrefixToRemove = "";

        /// <summary>
        /// 将数据库中变量名改为驼峰命名
        /// 如 user_name 改为 UserName
        /// </summary>
        /// <param name="name">变量名</param>
        /// <returns></returns>
        public static string GenVarName(string name, bool isTable = true)
        {
            tblNamePrefixToRemove = tblNamePrefixToRemove.Trim();
            if (isTable && tblNamePrefixToRemove.Length > 0 && name.StartsWith(tblNamePrefixToRemove))
                name = name.Substring(tblNamePrefixToRemove.Length);
            if (CamelCaseName)
            {
                string first = name.Substring(0, 1);

                name = name.Substring(1, name.Length - 1);
                name = first.ToUpper() + name;

                int index = name.IndexOf("_");
                while (index != -1)
                {
                    if (name.Length >= index + 2)
                    {
                        first = name.Substring(index + 1, 1);
                        string start = name.Substring(0, index);
                        string end = name.Substring(index + 2, name.Length - index - 2);
                        name = start + first.ToUpper() + end;

                        index = name.IndexOf("_");
                    }
                }
            }

            if (RemoveTableName_ && isTable) name = name.Replace("_", "");
            if (RemoveColumnName_ && (!isTable)) name = name.Replace("_", "");
            return name;
        }

        public static bool OverrideGetHashCode { get; set; }

        public static bool OverrideEquals { get; set; }
        public static bool GenerateColumn { get; set; } = true;
    }
}
